package edu.ncet.desktop.client;

import com.extjs.gxt.ui.client.event.BaseEvent;
import com.extjs.gxt.ui.client.event.ComponentEvent;
import com.extjs.gxt.ui.client.event.Events;
import com.extjs.gxt.ui.client.event.Listener;
import com.extjs.gxt.ui.client.event.WidgetListener;
import com.extjs.gxt.ui.client.widget.ContentPanel;
import com.extjs.gxt.ui.client.widget.Dialog;
import com.extjs.gxt.ui.client.widget.button.Button;
import com.google.gwt.core.client.GWT;

import edu.ncet.desktop.shared.AnswerSheetModel;
import edu.ncet.desktop.shared.QuestionModel;
import edu.ncet.desktop.shared.ResultModel;

public class ExaminationPanel extends AbstractExaminationPanel
{
	protected void loadQuestionPaper()
	{
		addWidgetListener( new WidgetListener(){
			public void widgetAttached( ComponentEvent ce )
			{
				navigateToQuestionComboEvents();
				populateQuestionNumberCombo();
				displayQuestionNumber( 0 );
			}
		} );
	}

	protected void populateQuestionNumberCombo()
	{
		navigateToQuestionCombo.getStore().removeAll();
		for ( int i = 0; i < questionSheet.size(); i++ )
		{
			NavigateToQuestionComboModel ans = null;
			Integer currentQuesNo = questionSheet.get( i ).getQuesNo();

			String comboImageStatus = IMAGE_UNANSWERED;
			if ( markedQuestions.contains( currentQuesNo ) )
				comboImageStatus = IMAGE_MARKED;
			else if ( answerSheet.containsAns( currentQuesNo ) )
				comboImageStatus = IMAGE_ANSWERED;

			ans = new NavigateToQuestionComboModel( String.valueOf( i + 1 ), comboImageStatus );
			navigatoToQuestionStore.add( ans );
		}
	}

	private void navigateToQuestionComboEvents()
	{
		navigateToQuestionCombo.addListener( Events.Expand, new Listener<BaseEvent>()
		{
			public void handleEvent( BaseEvent be )
			{
				populateQuestionNumberCombo();
			}
		} );

		navigateToQuestionCombo.addListener( Events.Select, new Listener<BaseEvent>()
		{
			public void handleEvent( BaseEvent be )
			{
				displayQuestionNumber( navigateToQuestionCombo.getStore().indexOf( navigateToQuestionCombo.getSelection().get( 0 ) ) );
			}
		} );
	}

	protected void displayQuestionNumber( Integer index )
	{
		currentQuestion = questionSheet.get( currentQuestionIndex = index );
		questionText.setValue( ( String ) currentQuestion.getQuestion() );
		ans1Text.setValue( ( String ) currentQuestion.getAns1() );
		ans2Text.setValue( ( String ) currentQuestion.getAns2() );
		ans3Text.setValue( ( String ) currentQuestion.getAns3() );
		ans4Text.setValue( ( String ) currentQuestion.getAns4() );
		populateAnswerIfAnswerisSelected();
		toggleMarkButtonIfQuestionMarked();

		navigateToQuestionCombo.setValue(navigatoToQuestionStore.getAt(index));
		enableDisableButtons();
		questionNumberLable.setText( "" );
		questionNumberLable.setValue( "Question :  " + getCurrentIndex1based() + " Of " + questionSheet.size() );
	}

	private void toggleMarkButtonIfQuestionMarked()
	{
		Boolean isQuestionMarked = markedQuestions.contains( currentQuestion.getQuesNo() );
		markButton.toggle( isQuestionMarked );
	}

	private void populateAnswerIfAnswerisSelected()
	{
		Boolean answerFoundFl = false;
		for ( Integer quesNo : answerSheet.getAvailableAns() )
		{
			if ( quesNo.equals( currentQuestion.getQuesNo() ) )
			{
				answerFoundFl = true;
				break;
			}
		}

		if ( answerFoundFl )
		{
			String answerSelected = answerSheet.getAnswerSheet().get( currentQuestion.getQuesNo() );
			int ansIndex = 0;
			if ( answerSelected.equals( "B" ) )
				ansIndex = 1;
			else if ( answerSelected.equals( "C" ) )
				ansIndex = 2;
			else if ( answerSelected.equalsIgnoreCase( "D" ) )
				ansIndex = 3;
			studentAnswerCombo.setValue( studentAnswerCombo.getStore().getAt( ansIndex ) );
		}
		else
		{
			studentAnswerCombo.clearSelections();
			studentAnswerCombo.setEmptyText( "Not Answered" );
		}
	}

	protected void studentAnswerUpdateAction()
	{
		logInfoToStudent( "Your Answer for Question No. " + getCurrentIndex1based() + " is updated." );
		Integer questionNo = currentQuestion.getQuesNo();
		String selectedItemText = studentAnswerCombo.getSelection().get( 0 ).get( "display" );
		answerSheet.setAnswer( questionNo, selectedItemText );
		if ( currentQuestionIndex != questionSheet.size() - 1 )
			displayQuestionNumber( currentQuestionIndex + 1 );
	}

	protected void finishExam( boolean isForced )
	{
		if ( !isForced && !validateForm() )
			return;
		timer.cancel();
		updateAnswerSheet( answerSheet );
		final ContentPanel panel = this;
		ExamsServiceAsync async = ( ExamsServiceAsync ) GWT.create( ExamsService.class );
		async.submitAnswerSheet( answerSheet, new Callback<ResultModel>()
		{
			@Override
			public void onSuccess( ResultModel resultModel )
			{
				removeAllWidgets( panel );
				populateMarksCard( resultModel );
			}
		} );
	}

	private void updateAnswerSheet( AnswerSheetModel answerSheet )
	{
		for ( QuestionModel qm : questionSheet )
		{
			if ( !answerSheet.containsAns( qm.getQuesNo() ) )
			{
				answerSheet.setUnanweredQuestions( qm.getQuesNo() );
			}
		}
	}

	private void populateMarksCard( ResultModel result )
	{
		MarksCardDisplayScreen marksCard = new MarksCardDisplayScreen(result);
		GlobalItem.getExamWindow().remove( this );
		GlobalItem.getExamWindow().setHeading("Marks card display system");
		GlobalItem.getExamWindow().add( marksCard );
		GlobalItem.getExamWindow().layout();
	}

	protected boolean validateForm()
	{
		if ( markedQuestions.size() != 0 )
		{
			logInfoToStudent( "One or More Question are still marked for Review..." );
			return false;
		}

		confirmOk = false;

		if ( answerSheet.getAvailableAns().size() != questionSheet.size() )
		{
			Dialog d = new Dialog()
			{
				@Override
				protected void onButtonPressed( Button button )
				{
					if ( button.getText().equalsIgnoreCase( Dialog.YES ) )
					{
						finishExam( true );
					}
					super.onButtonPressed( button );
				}
			};
			d.setHeading( "Confirm!" );
			d.addText( "One or More Questions are not answered. Continue ?" );
			d.setBodyStyle( "fontWeight:bold;padding:13px;" );
			d.setSize( 300, 150 );
			d.setHideOnButtonClick( true );
			d.setButtons( Dialog.YESNO );
			d.show();
			return confirmOk;
		}
		return true;
	}
}
